package br.ufc.apsoo.controllers;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;

import org.joda.time.LocalDate;

import com.google.common.base.Strings;

import br.com.caelum.vraptor.Get;
import br.com.caelum.vraptor.Path;
import br.com.caelum.vraptor.Post;
import br.com.caelum.vraptor.Resource;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.Validator;
import br.com.caelum.vraptor.validator.ValidationMessage;
import br.ufc.apsoo.models.Apartamento;
import br.ufc.apsoo.models.Hospede;
import br.ufc.apsoo.models.Reserva;
import br.ufc.apsoo.models.Servico;
import br.ufc.apsoo.repositories.TodasReservas;
import br.ufc.apsoo.repositories.TodosApartamentos;
import br.ufc.apsoo.repositories.TodosServicos;

@Resource
public class RelatorioController {

	private final Result result;
	private final TodasReservas todasReservas;
	private final TodosServicos todosServicos;
	private final TodosApartamentos todosApartamentos;
	private final Validator validator;

	public RelatorioController(Result result, TodasReservas todasReservas,
			TodosServicos todosServicos, TodosApartamentos todosApartamentos,
			Validator validator) {
		this.result = result;
		this.todasReservas = todasReservas;
		this.validator = validator;
		this.todosServicos = todosServicos;
		this.todosApartamentos = todosApartamentos;
	}

	@Get
	@Path("/relatorio/hospede/apartamento")
	public void apartamento(String nomeParaPesquisa) {
		if (Strings.isNullOrEmpty(nomeParaPesquisa)) {
			validator.add(new ValidationMessage(
					"Preencha parte do nome para a pesquisa!",
					"erro"));
		} else {
			List<Reserva> reservas = todasReservas.ocupadaPor(nomeParaPesquisa);

			if (reservas == null || reservas.isEmpty()) {
				validator.add(new ValidationMessage(
						"Nenhum apartamento encontrado para este hóspede!",
						"erro"));
			} else {
				result.include("reservas", reservas);
			}
		}
		validator.onErrorUsePageOf(this).hospede();
	}

	@Get
	@Path("/relatorio/faturamento/evolucao")
	public void evolucao() {
		LocalDate data = new LocalDate(new Date());
		Integer mes = data.getMonthOfYear();
		result.include("faturamentoUmMesAtras",
				todasReservas.queFaturaramEm(mes - 1));
		result.include("umMesAtras", (mes - 1) + "/" + data.getYear());
		result.include("faturamentoDoisMesesAtras",
				todasReservas.queFaturaramEm(mes - 2));
		result.include("doisMesesAtras", (mes - 2) + "/" + data.getYear());
		result.include("faturamentoTresMesesAtras",
				todasReservas.queFaturaramEm(mes - 3));
		result.include("tresMesesAtras", (mes - 3) + "/" + data.getYear());
	}

	@Get
	@Path("/relatorio/servico/faturamento/inicio/{inicio*}/fim/{fim*}")
	public List<Servico> faturamento(Date inicio, Date fim) {
		List<Servico> servicos = null;
		if (inicio == null || fim == null) {
			validator.add(new ValidationMessage(
					"Preencha as datas para fazer a pesquisa!", "erro"));
		} else {
			if (inicio.after(fim)) {
				validator.add(new ValidationMessage(
						"A data de início deve ser menor que a data de fim!",
						"erro"));
			} else {
				servicos = todosServicos.queMaisFaturaramEntre(inicio, fim);
			}
		}

		validator.onErrorUsePageOf(this).servico();

		return servicos;
	}

	@Get
	@Path("/relatorio/hospede")
	public void hospede() {
	}

	@Get
	@Path("/relatorio")
	public void index() {
	}

	@Get
	@Path("/relatorio/taxa/ocupacao/{data*}")
	public void ocupacao(Date data) {
		if (data == null) {
			data = new Date();
		}
		List<Apartamento> apartamentos = todosApartamentos.ocupadosEm(data);
		result.include("apartamentos", apartamentos);
		result.include("quantidadeTotal", todosApartamentos.traz().size());
		result.include("quantidadeOcupada", apartamentos.size());
		result.include("taxaDeOcupacao", new BigDecimal(apartamentos.size())
				.divide(new BigDecimal(todosApartamentos.traz().size()), 6,
						RoundingMode.HALF_UP));
	}

	@Get
	@Path("/relatorio/servico")
	public void servico() {
	}

	@Get
	@Path("/relatorio/taxa")
	public void taxa() {
	}
}
